"""
Package containing the logic and tools used by the Oklahoma Next-Generation
9-1-1 GIS Toolkit for ArcGIS Pro.

Package initialization sets up logging and patches a few methods in the
``arcgis`` package.

A log file is written to ``../ng911ok.log``.

See :func:`__patch` for details on method patching.
"""
__version__ = "3.1.0-beta.2"

import datetime
import logging
import sys
from inspect import getfullargspec
from pathlib import Path

import arcpy

# noinspection PyProtectedMember
import arcgis.features.geo._array  # Used for patching
import arcgis.geometry  # Used for patching
import pandas.core.arrays.base  # Used for patching

try:
    __logging_file_path = Path(__file__).parent.parent / "ng911ok.log"
    logging.basicConfig(filename=__logging_file_path, encoding="utf-8", level=logging.DEBUG)
except:
    logging.basicConfig(stream=sys.stdout, encoding="utf-8", level=logging.DEBUG)
install_info = arcpy.GetInstallInfo()
__logger = logging.getLogger(__name__)
__logger.info(f"==== LOADED ng911ok v{__version__} @ {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')} ====\n     ArcPy Info: {install_info['ProductName']} {install_info['Version']} ({install_info['LicenseLevel']})")

# noinspection PyProtectedMember
def __patch():
    """
    Patches, as necessary, a few functions in this package's dependencies.

    .. list-table::
       :widths: auto

       * - ``arcgis.features.geo._array.GeoArray._from_factorized()``
         - Adds an argument (``original``) missing from the signature and
           defaults it to ``None``
       * - ``arcgis.geometry._types.Polyline.__getitem__()``
         - When key ``paths`` is requested from a ``Polyline`` that has no
           ``paths`` key, returns ``curvePaths`` instead
       * - ``arcgis.geometry._types.Polygon.__getitem__()``
         - When key ``rings`` is requested from a ``Polygon`` that has no
           ``rings`` key, returns ``curveRings`` instead
    """
    # Patch arcgis.features.geo._array.GeoArray._from_factorized (if needed)
    extensionarray_from_factorized_method_args = getfullargspec(pandas.core.arrays.base.ExtensionArray._from_factorized).args
    geoarray_from_factorized_method_args = getfullargspec(arcgis.features.geo._array.GeoArray._from_factorized).args
    if len(extensionarray_from_factorized_method_args) > len(geoarray_from_factorized_method_args):
        # Patch GeoArray._from_factorized() because, as implemented in package
        # ``arcgis`` v2.3.0, GeoArray's method does not accept the (unused)
        # argument ``original`` that pandas passes to it
        # noinspection PyUnusedLocal
        def _patched_from_factorized(cls, values, original=None):
            return cls(values)

        arcgis.features.geo._array.GeoArray._from_factorized = classmethod(_patched_from_factorized)
        __logger.debug("Patched arcgis.features.geo._array.GeoArray._from_factorized.")

    # Patch arcgis.geometry.Polyline.__getitem__ to handle geometry with curves
    if arcgis.geometry.Polyline.__getitem__.__name__ != "_patched_polyline_getitem__":
        original_polyline_getitem = arcgis.geometry.Polyline.__getitem__
        def _patched_polyline_getitem__(self, k):
            if k == "paths" and "paths" not in self:
                return original_polyline_getitem(self, "curvePaths")
            else:
                return original_polyline_getitem(self, k)
        arcgis.geometry.Polyline.__getitem__ = _patched_polyline_getitem__
        __logger.debug("Patched arcgis.geometry.Polyline.__getitem__.")

    # Patch arcgis.geometry.Polygon.__getitem__ to handle geometry with curves
    if arcgis.geometry.Polygon.__getitem__.__name__ != "_patched_polygon_getitem__":
        original_polygon_getitem = arcgis.geometry.Polygon.__getitem__
        def _patched_polygon_getitem__(self, k):
            if k == "rings" and "rings" not in self:
                return original_polygon_getitem(self, "curveRings")
            else:
                return original_polygon_getitem(self, k)
        arcgis.geometry.Polygon.__getitem__ = _patched_polygon_getitem__
        __logger.debug("Patched arcgis.geometry.Polygon.__getitem__.")

__patch()
